%% 注意：当元件分组内、组间时末尾会有0，因此传入该函数之前将pc、gc的0去掉
%% 参数说明：SMT对象、迭代次数、种群数量、雄狮比例、母狮比例
function [best_life,dis_plot] = SMT_LSO_Run(Smt,Gen_Size,Pop_Zize,Lion_Prop,Lioness_Prop)
    %% 初始化狮群（pop_size个个体）
    %% 如果不使用初始解，而使用随机初始化，则需要计算每一个体的编码序列lso_mnsc_sequen！！！
    compo_len = Smt.nC;%元件数量
    zero_num =Smt.head_num - rem(Smt.nC,Smt.head_num);%补零的个数
    for j = 1:Pop_Zize
        %%  初始化的奇数个元件序列尾部补了零，距离以及解码函数考虑了补零，但对偶数个元件可能报错
        %% 因此下面的随机种群后续可能需要稍作处理
        lives(j) = Smt.life;
%         lives(j).pc = randperm(compo_len,compo_len);
%         if zero_num~=0
%             lives(j).pc(end+1:end+zero_num) = 0;%奇数要补零
%         end
%         %% 贴放元件每一组应该和每一循环吸头吸取的元件相同，只是组内顺序不同,因此gc一定要分组
%         lives(j).gc = lives(j).pc;
%         lives(j).fc = randperm(Smt.nK,Smt.nK);
        %% 元件序列转换为组间、组内序列，由于距离计算函数需要的元件序列格式为贴片循环*贴头数，所以需要将元件以head_num个为一组分成Smt.R组
        alpha_conv = reshape(lives(j).alpha,[Smt.R,Smt.head_num]);
        zeta_conv = alpha_conv;
        lives(j).alpha = alpha_conv;%转换之后元件分组格式和遗传算法一致
        lives(j).zeta = alpha_conv;
        lives(j).lso_mnsc_sequen = randperm(Smt.R,Smt.R);%% 初始化的编码序列都不同
        fc = Feeder_Code(lives(j).fc,Smt.nS);%供料槽元器件类型分配
        %% 计算每一个体的适应度
        lives(j).dis_sum = Dis_Sum(Smt,alpha_conv,zeta_conv,fc);
        lives(j).fitness = 10000/lives(j).dis_sum;%以距离的倒数作为适应值，因计算的距离数值较大所以倒数值放大一万倍
    end
    %% 计算初始种群的适应度值，按降序排序，依次划分为雄狮、母狮、幼狮，如比例分别为：0.2 0.2 0.6
%     for i = 1:Pop_Zize-1
%         for j = 1:Pop_Zize-i
%             if lives(j).fitness < lives(j+1).fitness
%                 temp = lives(j);
%                 lives(j) = lives(j+1);
%                 lives(j+1) = temp;
%             end
%         end
%     end
    Lion_num = floor(Lion_Prop*Pop_Zize);
    Lioness_num = floor(Lioness_Prop*Pop_Zize);
    LionCubs_num = Pop_Zize-Lion_num-Lioness_num;
    Lion_lives = lives(1:Lion_num);%雄狮种群
    Lioness_lives = Lion_lives;%母狮种群
    LionCubs_lives = lives(Lioness_num+Lion_num+1:Pop_Zize);%幼狮种群
    %% 初始化参数
    rand_rate = 0.9;
    FeCrossNum = 4;
%     Lion_best_life = Lion_lives(1);%初始化雄狮k代群体最优位置
    history_best_life = LionCubs_lives(1);%初始化幼狮历史最优个体
%     Lioness_best_life = Lion_lives(1);%母狮历史最优
    Lioness_best_life = lives(1);;%母狮历史最优
    Lion_best_life = lives(1);%初始化雄狮k代群体最优位置
    num = 1;
    dis = 0;
    %% 迭代
    for k = 1:Gen_Size
        %% 幼狮适应度降序排列
        for i = 1:LionCubs_num
            for j = 1:LionCubs_num-i
                if LionCubs_lives(j).fitness < LionCubs_lives(j+1).fitness
                    temp = LionCubs_lives(j);
                    LionCubs_lives(j) = LionCubs_lives(j+1);
                    LionCubs_lives(j+1) = temp;
                end
            end
        end
        gen_best_life(k) = LionCubs_lives(1);%更新k代幼狮群体最优个体
        if history_best_life.fitness < gen_best_life(k).fitness
            history_best_life = gen_best_life(k);%更新目前所有代中幼狮种群最优的个体
        end
        %% 雄狮
%         for i = 1:Lion_num %雄狮使用2opt更新
%             last_live = Lion_best_life;
%              Lion_lives(i) = LSO_2opt_Mut(Smt,Lion_best_life,rand_rate,FeCrossNum);
%         end
        
        
       % 雄狮适应度降序排列
        for i = 1:Lion_num-1
            for j = 1:Lion_num-i
                if Lion_lives(j).fitness < Lion_lives(j+1).fitness
                    temp = Lion_lives(j);
                    Lion_lives(j) = Lion_lives(j+1);
                    Lion_lives(j+1) = temp;
                end
            end
        end
        
        if Lion_best_life.fitness < Lion_lives(1).fitness
            Lion_best_life = Lion_lives(1);
            disp(['雄狮第',num2str(k),'代最短距离为:',num2str(Lion_best_life.dis_sum)])
        end
        
        %% 母狮
        choose = randperm(4,1);
        al = 0.03;
        for i=1:Lioness_num%更新母狮，如果mnsc操作产生了更优的子代则会返回子代，否则返回父代1
            Lioness_lives(i) = LSO_MNSC(Smt,Lioness_best_life,Lioness_lives(i),2,al);
            dis(num) = Lioness_lives(i).dis_sum;
            num = num+1;
        end

       %% 产生的优质母狮子代适应度降序排列
        for i = 1:Lioness_num
            for j = 1:Lioness_num-i
                if Lioness_lives(j).fitness < Lioness_lives(j+1).fitness
                    temp = Lioness_lives(j);
                    Lioness_lives(j) = Lioness_lives(j+1);
                    Lioness_lives(j+1) = temp;
                end
            end
        end
        %如果mnsc操作后的母狮最优个体优于之前的母狮最优个体，则更新母狮最优个体
        if Lioness_lives(1).fitness > Lioness_best_life.fitness
            Lioness_best_life = Lioness_lives(1);
            disp(['母狮第',num2str(k),'代最短距离为:',num2str(Lioness_best_life.dis_sum)])
        end
        
      %% 精英策略，最优个体若在种群中不做处理，若不在，则插入种群，再删掉一个
        for lli = 1:Lioness_num
            if Lioness_lives(lli).fitness == Lioness_best_life.fitness
                break
            end
            Lioness_lives(length(Lioness_lives)) = [];
            Lioness_lives(length(Lioness_lives)) = Lioness_best_life;
            
        end  
        
        
        
        
%         if Lioness_best_life.fitness > Lion_best_life.fitness
%             Lion_best_life = Lioness_best_life;
%             disp("母狮优于雄狮#########")
%         end
              
%         for i = 1:LionCubs_num%更新幼狮,由于LSO_MNSC内部对比的是父代1的适应值，因此参数2、3的父代顺序应该会影响算法效果
%             q = randperm(3,1);
%             if q == 1
%                 r = randperm(length(Lioness_lives),1);
%                 LionCubs_lives(i) = LSO_MNSC(Smt,Lioness_lives(i),Lioness_lives(i),choose,al);%
%             end
%             if q == 2
%                 LionCubs_lives(i) = LSO_MNSC(Smt,history_best_life,LionCubs_lives(i),choose,al);%
%             end
%             if q == 3
%                 
%             end
%             
%         end
%         %如果幼狮最优个体优于雄狮最优个体，则更新雄狮最优个体
%         if history_best_life.fitness > Lion_best_life.fitness
%             Lion_best_life = history_best_life;
%             disp('幼狮最优个体优于雄狮最优个体')
%         else
%             history_best_life = Lion_best_life;
%         end

        disp(['已迭代',num2str(k),'次'])
        disp(['母狮目前最短距离为:',num2str(Lioness_best_life.dis_sum)])
%         disp(['幼狮目前最高适应度为:',num2str(history_best_life.fitness)])
%         disp(['幼狮目前最短距离为:',num2str(history_best_life.dis_sum)])
        disp(['雄狮目前最短距离为:',num2str(Lion_best_life.dis_sum)])
    end
    best_life = Lion_best_life;
    dis_plot = dis;    
end